home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / msg-clean / msg-clean.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  4.7 KB  |  217 lines

  1. /* msg_clean.c: message cleanout channel */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/msg-clean/RCS/msg-clean.c,v 6.0 1991/12/18 20:11:18 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/msg-clean/RCS/msg-clean.c,v 6.0 1991/12/18 20:11:18 jpo Rel $
  9.  *
  10.  * $Log: msg-clean.c,v $
  11.  * Revision 6.0  1991/12/18  20:11:18  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "util.h"
  19. #include "head.h"
  20. #include "qmgr.h"
  21. #include "q.h"
  22. #include "prm.h"
  23. #include <sys/param.h>
  24. #include <sys/stat.h>
  25. #include "sys.file.h"
  26. #include <isode/usr.dirent.h>
  27.  
  28.  
  29. extern char     *quedfldir;
  30. extern char     *chndfldir;
  31. extern CHAN     *ch_nm2struct();
  32. extern void    getfpath(), rd_end(), sys_init(), err_abrt();
  33. /* CHANGE LATER */
  34. CHAN            *mychan;
  35.  
  36. static struct type_Qmgr_DeliveryStatus *process ();
  37. static int initialise ();
  38. static int security_check ();
  39. static void dirinit ();
  40. int    error;
  41. /*   */
  42. /* main routine */
  43.  
  44. main (argc, argv)
  45. int     argc;
  46. char    **argv;
  47. {
  48.     sys_init(argv[0]);
  49.     dirinit ();
  50. #ifdef PP_DEBUG
  51.     if (argc>1 && (strcmp(argv[1],"debug") == 0))
  52.         debug_channel_control(argc,argv,initialise, process, NULLIFP);
  53.     else
  54. #endif
  55.         channel_control (argc, argv, initialise, process, NULLIFP);
  56. }
  57.  
  58. /*   */
  59. /* routine to move to correct place in file system */
  60.  
  61. static void dirinit ()
  62. {
  63.     if (chdir (quedfldir) < 0)
  64.         err_abrt (RP_LIO, " Unable to change directory to '%s'",
  65.               quedfldir);
  66. }
  67.  
  68. /*   */
  69. /* channel initialise routine */
  70.  
  71. static int initialise (arg)
  72. struct type_Qmgr_Channel *arg;
  73. {
  74.     char *name;
  75.  
  76.     name = qb2str(arg);
  77.  
  78.     if ((mychan = ch_nm2struct(name)) == NULLCHAN) {
  79.         PP_OPER(NULLCP,
  80.             ("Channel '%s' not known",name));
  81.         if (name != NULL) free(name);
  82.         return NOTOK;
  83.     }
  84.     /* check if a cleanout channel */
  85.     if (mychan -> ch_chan_type != CH_DELETE) {
  86.         PP_OPER (NULLCP,
  87.              ("Channel '%s' is not a msg deletion channel",
  88.               name));
  89.         if (name) free (name);
  90.         return NOTOK;
  91.     }
  92.     if (name != NULL) free(name);
  93.     return OK;
  94. }
  95.  
  96. /*   */
  97. /* routine called to do clean out */
  98. static struct type_Qmgr_DeliveryStatus *process (arg)
  99. struct type_Qmgr_ProcMsg *arg;
  100. {
  101.     char    *this_msg = NULL;
  102.     struct stat statbuf;
  103.  
  104.     dirinit ();
  105.     delivery_init(arg->users);
  106.     delivery_setall(int_Qmgr_status_messageFailure);
  107.  
  108.     if (security_check(arg) != TRUE)
  109.         return deliverystate;
  110.  
  111.     /* ok-you asked for it-remove message */
  112.     this_msg = qb2str (arg->qid);
  113.  
  114.     PP_LOG(LLOG_NOTICE,
  115.            ("Cleaning out msg %s", this_msg));
  116.  
  117.  
  118.     error = FALSE;
  119.  
  120.     /*
  121.      * This stuff here to try and win efficiency.
  122.      * In a crowded queue, the chdir business should cut down
  123.      * the time spent in kernel namei routine.
  124.      */
  125.     if (chdir (this_msg) == 0) {
  126.         (void) recrm (".");
  127.         dirinit ();
  128.         if (rmdir (this_msg) == NOTOK)
  129.             error = TRUE;
  130.     }
  131.     else if (stat(this_msg, &statbuf) == OK) {
  132.         if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
  133.             if (unlink (this_msg) == NOTOK)
  134.                 error = TRUE;
  135.         }
  136.     }
  137.     if (error == TRUE)
  138.         PP_SLOG (LLOG_EXCEPTIONS, this_msg,
  139.              ("Unable to remove directory"));
  140.  
  141.     if (this_msg != NULL) free(this_msg);
  142.     /* create return values */
  143.     if (error == FALSE)
  144.         delivery_setall(int_Qmgr_status_success);
  145.     return deliverystate;
  146.  
  147. }
  148.  
  149. /*   */
  150. /* routine to check if allowed to remove this message */
  151. static int security_check (msg)
  152. struct type_Qmgr_ProcMsg *msg;
  153. {
  154.     char            *msg_file = NULL, *msg_chan = NULL;
  155.     struct prm_vars prm;
  156.     Q_struct        que;
  157.     ADDR            *sender = NULL;
  158.     ADDR            *recips = NULL;
  159.     int             rcount,
  160.             result;
  161.     ADDR            *ix = NULL;
  162.     char        msgname[MAXPATHLENGTH];
  163.     struct stat    statbuf;
  164.     extern char     *aquefile;
  165.  
  166.     prm_init (&prm);
  167.     q_init (&que);
  168.  
  169.     result = TRUE;
  170.     msg_file = qb2str (msg->qid);
  171.     msg_chan = qb2str (msg->channel);
  172.  
  173.     if ((mychan == NULLCHAN) || (strcmp(msg_chan,mychan->ch_name) != 0)) {
  174.         PP_LOG(LLOG_EXCEPTIONS,
  175.                ("Wrong channel name '%s'",msg_chan));
  176.         result = FALSE;
  177.     }
  178.  
  179.     if (rp_isbad(rd_msg_file(msg_file,&prm,&que,
  180.                 &sender,&recips,&rcount,
  181.                 RDMSG_RDONLY))) {
  182.         (void) sprintf (msgname, "%s/%s", msg_file, aquefile);
  183.         if (stat(msgname, &statbuf) != OK) {
  184.             /* does not exist so effectively removed */
  185.             if (msg_file != NULL) free(msg_file);
  186.             if (msg_chan != NULL) free(msg_chan);
  187.             return TRUE;
  188.         }
  189.         PP_LOG(LLOG_EXCEPTIONS,
  190.                ("Can't read message '%s'",msg_file));
  191.         result = FALSE;
  192.     }
  193.  
  194.     /* unlock file */
  195.     rd_end();
  196.  
  197.     /* now check the recips */
  198.     if (result == TRUE) {
  199.         ix = que.Raddress;
  200.         while ((ix != NULL) && (ix->ad_status == AD_STAT_DONE))
  201.             ix = ix->ad_next;
  202.         if (ix != NULL) {
  203.             PP_LOG(LLOG_EXCEPTIONS,
  204.                    ("recipient %d status not DONE: '%s'",
  205.                 ix->ad_no,msg_file));
  206.             result = FALSE;
  207.         }
  208.     }
  209.  
  210.     /* free all storage used */
  211.     if (msg_file != NULL) free(msg_file);
  212.     if (msg_chan != NULL) free(msg_chan);
  213.     q_free (&que);
  214.     prm_free(&prm);
  215.     return result;
  216. }
  217.